package com.qinglei.recoup.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.qinglei.recoup.common.annotation.Log;
import com.qinglei.recoup.common.controller.BaseController;
import com.qinglei.recoup.common.domain.CommonConstant;
import com.qinglei.recoup.common.domain.CommonRes;
import com.qinglei.recoup.common.exception.RecoupException;
import com.qinglei.recoup.common.exception.RedisConnectException;
import com.qinglei.recoup.common.service.RedisService;
import com.qinglei.recoup.common.tenant.TenantContextHolder;
import com.qinglei.recoup.common.utils.AesEncryptUtil;
import com.qinglei.recoup.common.utils.MD5Util;
import com.qinglei.recoup.common.utils.RecoupUtil;
import com.qinglei.recoup.system.domain.Tenant;
import com.qinglei.recoup.system.domain.User;
import com.qinglei.recoup.system.pojo.AddUserParam;
import com.qinglei.recoup.system.pojo.AdminUserVO;
import com.qinglei.recoup.system.pojo.DeanBedVO;
import com.qinglei.recoup.system.pojo.PageVO;
import com.qinglei.recoup.system.pojo.UpdatePasswordParam;
import com.qinglei.recoup.system.pojo.UpdateUserParam;
import com.qinglei.recoup.system.pojo.UserDetailVO;
import com.qinglei.recoup.system.pojo.UserSearchParam;
import com.qinglei.recoup.system.service.DeanBedService;
import com.qinglei.recoup.system.service.TenantService;
import com.qinglei.recoup.system.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "用户相关控制器-石-已完成")
@Slf4j
@Validated
@RestController
@RequestMapping("user")
public class UserController extends BaseController {

    private String message;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private TenantService tenantService;
    @Autowired
    private DeanBedService deanBedService;

    @ApiOperation(value = "查询用户详情")
    @ApiImplicitParam(name = "userId", value = "用户ID", paramType = "path", dataType = "Long", required = true)
    @GetMapping("/{userId}")
    public CommonRes<UserDetailVO> detail(@NotNull(message = "{required}") @PathVariable Long userId) {
        User user = this.userService.findById(userId);
        if (user == null) {
            return CommonRes.failed("用户不存在");
        }
        UserDetailVO userDetailVO = new UserDetailVO();
        userDetailVO.setUserId(user.getId());
        userDetailVO.setName(user.getName());
        userDetailVO.setMobile(user.getMobile());
        userDetailVO.setRoleId(user.getRoleId());
        userDetailVO.setRoleName(user.getRoleName());
        userDetailVO.setPassword("");
        Tenant tenant = tenantService.getById(user.getTenantId());
        if (tenant != null && tenant.getAdminUserId().equals(user.getId())) {
            userDetailVO.setNoDelete(1);
        }

        return CommonRes.ok(userDetailVO);
    }

    @ApiOperation(value = "添加账号")
    @Log("添加账号")
    @PostMapping
//    @RequiresPermissions("user:add")
    public CommonRes<Long> addUser(@RequestBody @Valid AddUserParam param) throws RecoupException, RedisConnectException {
        String lockKey = CommonConstant.USER_ADD_LOCK_PREFIX + param.getMobile();
        Long setnx = redisService.setnx(lockKey, param.getMobile());
        if (setnx == 0) {
            return CommonRes.failed("请勿重复添加账号");
        }
        redisService.expire(lockKey, CommonConstant.USER_ADD_LOCK_TIMEOUT);

        try {
            User user = new User();
            BeanUtils.copyProperties(param, user);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("name",param.getName());
            List<User> oldUsers = userService.list(queryWrapper);
            if(oldUsers!=null && oldUsers.size()>0){
                return CommonRes.failed("姓名已经存在");
            }
            this.userService.createUser(user);
            return CommonRes.ok(user.getId());
        } catch (RecoupException e) {
            message = "新增用户失败";
            log.error(message, e);
            throw e;
        } catch (Exception e) {
            message = "新增用户失败";
            log.error(message, e);
            throw new RecoupException(message);
        } finally {
            redisService.del(lockKey);
        }
    }

    @ApiOperation(value = "修改账号")
    @Log("修改账号")
    @PutMapping
//    @RequiresPermissions("user:update")
    public CommonRes<Object> updateUser(@RequestBody @Valid UpdateUserParam param) throws RecoupException {
        try {
            User user = new User();
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("name",param.getName());
            queryWrapper.ne("id",param.getUserId());
            List<User> oldUsers = userService.list(queryWrapper);
            if(oldUsers!=null && oldUsers.size()>0){
                return CommonRes.failed("姓名已经存在");
            }
            BeanUtils.copyProperties(param, user);
            user.setId(param.getUserId());
            this.userService.updateUser(user);
            return CommonRes.ok("修改用户成功");
        } catch (Exception e) {
            message = "修改用户失败";
            log.error(message, e);
            throw new RecoupException(message);
        }
    }

    @ApiOperation(value = "删除账号")
    @ApiImplicitParam(name = "userIds", value = "用户ID，多个逗号分隔", paramType = "path", dataType = "String", required = true)
    @Log("删除账号")
    @DeleteMapping("/{userIds}")
//    @RequiresPermissions("user:delete")
    public CommonRes<Object> deleteUsers(@NotBlank(message = "{required}") @PathVariable String userIds) throws RecoupException {
        try {
            String[] ids = userIds.split(StringPool.COMMA);
            this.userService.deleteUsers(ids);
            return CommonRes.ok("删除用户成功");
        } catch (Exception e) {
            message = "删除用户失败";
            log.error(message, e);
            throw new RecoupException(message);
        }
    }

    @ApiOperation(value = "用户(管理员和院长)分页列表")
    @GetMapping
    public CommonRes<PageVO<AdminUserVO>> getPageList(UserSearchParam pageParam) {
        User userQuery = new User();
        userQuery.setRoleId("1,2");
        userQuery.setTenantId(TenantContextHolder.getTenantId());
        userQuery.setName(pageParam.getName());
        pageParam.setSortField("u.create_time");
        pageParam.setSortOrder("descend");
        Integer tenantId = TenantContextHolder.getTenantId();
        Tenant tenant = tenantService.getById(tenantId);
        IPage<User> pageRes = this.userService.findUserDetail(userQuery, pageParam);
        PageVO<AdminUserVO> userDetailVOPage = new PageVO<>();
        if (pageRes != null && pageRes.getTotal() > 0) {
            List<AdminUserVO> list = pageRes.getRecords().stream().map(user -> {
                AdminUserVO adminUserVO = new AdminUserVO();
                adminUserVO.setUserId(user.getId());
                adminUserVO.setName(user.getName());
                adminUserVO.setMobile(user.getMobile());
                adminUserVO.setRoleId(user.getRoleId());
                adminUserVO.setRoleName(user.getRoleName());
                adminUserVO.setPassword("");
                if (tenant != null && tenant.getAdminUserId().equals(user.getId())) {
                    adminUserVO.setNoDelete(1);
                }
                List<DeanBedVO> deanBedList = deanBedService.getDeanBedList(user.getId());
                adminUserVO.setDeanBedList(deanBedList);
                return adminUserVO;
            }).collect(Collectors.toList());
            userDetailVOPage.setTotal(pageRes.getTotal());
            userDetailVOPage.setRows(list);
        }

        return CommonRes.ok(userDetailVOPage);
    }

    @ApiOperation(value = "[2.0新增]用户修改密码")
    @PutMapping("/password")
    public CommonRes<Object> updatePassword(@RequestBody @Valid UpdatePasswordParam param) {
        User currentUser = RecoupUtil.getCurrentUser();

        String oldPassword = MD5Util.encrypt(AesEncryptUtil.decrypt(param.getOldPassword()));
        if (StringUtils.isEmpty(oldPassword) || !StringUtils.equals(currentUser.getPassword(), oldPassword)) {
            return CommonRes.failed("原密码不正确");
        }
        String newPassword = AesEncryptUtil.decrypt(param.getNewPassword());
        if (newPassword == null || newPassword.length() < 6 || newPassword.length() > 16) {
            return CommonRes.failed("新密码有效长度6到16个字符");
        }
        try {
            userService.updatePassword(currentUser.getId(), newPassword);
        } catch (Exception e) {
            log.error("updatePassword error newPassword:{}", param.getNewPassword(), e);
            return CommonRes.failed("新密码更新失败");
        }
        return CommonRes.ok();
    }

}
